package com.xplay.xpocker.message.action.mahjong;

import com.xplay.xpocker.entity.mahjong.MahjongBillBuilder;
import com.xplay.xpocker.entity.mahjong.MahjongRoomBuilder;
import com.xplay.xpocker.meta.MessageContent;
import com.xplay.xpocker.meta.realize.MahjongRoomEntity;
import com.xplay.xpocker.entity.mahjong.MahjongUserTask;
import com.xplay.xpocker.message.action.MessageAnnotation;
import com.xplay.xpocker.message.action.MessageStrategy;
import com.xplay.xpocker.meta.realize.MahjongUserChannel;
import com.xplay.xpocker.meta.user.MetaUserChannel;
import com.xplay.xpocker.service.mahjong.IDiskPartService;
import com.xplay.xpocker.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

import static com.xplay.xpocker.util.DictionaryConst.MahjongAction.*;

/**
 * @author wanjie
 * @date 2021/3/17 21:43
 */
@MessageAnnotation(action = CARD_HU, type = {DictionaryConst.RoomTypeConst.WZ_MAHJONG})
@Service
public class MessageCardHu extends MessageStrategy {
    private static final Logger log = LoggerFactory.getLogger(MessageCardHu.class);

    @Autowired
    private IDiskPartService diskPartService;
    @Autowired
    private RedisUtil redisUtil;


    // 手牌杠  以及被人打出来的牌杠

    @Override
    public void doMessage(MahjongUserChannel userChannel, MessageContent message, MahjongRoomEntity roomInfo) {
        /**
         * 加倍的几种情况
         * 1. 杠上 胡牌
         * 2. 胡牌人  报叫
         * 3. 放炮人报叫
         * 4. 前 3
         * 5. 后 4
         */
        Integer maxTurns = roomInfo.getRule().getTurns();
        // 移除不需要胡牌的任务
        removeNoHuActionTask(roomInfo, userChannel);
        Boolean loadingDealWith = false;
        // 将手牌分为 3个组     小胡  2组以上 并且有顺子
        String prevUserId = roomInfo.getCurrentExportUserId();
        MahjongUserTask userTask = roomInfo.getUserTask(userChannel.getUserId());
        userTask.setDealWith(true);
        MahjongUserChannel prevUserInfo = roomInfo.getUserInfoByUserId(prevUserId);
        WzHuCardType huCardType = null;
        Integer prevExportCard = roomInfo.getCurrentExportCard();
        // 如果出牌人是自己 那么就是自摸
        if (roomInfo.getUserCards().get(userChannel.getUserId()).size()%3 == 2) {
            if (roomInfo.getLicensingCard() == null) {
                roomInfo.setLicensingCard(roomInfo.getUserCards().get(userChannel.getUserId()).get(0));
            }
            userChannel.setHuCard(roomInfo.getLicensingCard());
            userChannel.setWin(true);
            userChannel.setWinCount(userChannel.getWinCount() + 1);
            userChannel.setHuCard(roomInfo.getLicensingCard());
            huCardType = CardUtil.checkCardType(roomInfo.getUserCards().get(userChannel.getUserId()), roomInfo.getUserAllTouchBarCards(userChannel.getUserId()));
            huCardType.addTurns(roomInfo.getCurrentBarUser() != null, userChannel.isListening(), roomInfo.checkFistAndLastFour(), roomInfo.getRule().getRules().contains(DictionaryConst.MahjongRuleConst.SING_UP) && huCardType.isThreeSteps());
            Integer userDefaultTurns = huCardType.getTurns();
            BusinessAssertion.isNull("炸胡", huCardType);
            CardUtil.removeCard(roomInfo.getUserCards().get(userChannel.getUserId()), roomInfo.getLicensingCard());
            // 为每一个玩家   减去相应的分数
            log.info(huCardType.toString());
            Integer fraction = 0;
            for (MahjongUserChannel notWinnerUser : roomInfo.notWinnerUsers()) {
                huCardType.addTurns(notWinnerUser.isListening());
                fraction += huCardType.getFraction(maxTurns);
                roomInfo.addBillHistory(new MahjongBillBuilder().init(CardUtil.ACTION_COVER + CardUtil.ACTION_BY_OWN, huCardType.getType(), notWinnerUser.getUserId(), userChannel.getUserId(), -huCardType.getFraction(maxTurns)).build());
                huCardType.setTurns(userDefaultTurns);
            }
            roomInfo.addBillHistory(new MahjongBillBuilder().init(CardUtil.ACTION_BY_OWN, huCardType.getType(), userChannel.getUserId(), userChannel.getUserId(), fraction).build());
            huCardType.setHuType("自摸");
            roomInfo.addBillClearingInfo(userChannel, true);
            diskPart.get(roomInfo.getCode()).notifyMessage(new MessageContent<String>().initActionAndUId(CARD_HU,userChannel.getUserId()), null);
            licensingCard(false, userChannel.getSeq(), roomInfo, loadingDealWith, diskPartService, true);
        } else {
            // 如果还有 自己以外的 有胡的   那么就不能直接胡牌   就需要等待 另外个人处理
            // 别人放炮
            // 获取除开自己以外的 带有胡牌行为的 并且没有处理的
            ArrayList<MahjongUserTask> notDealWithHuTask = getHuTask(roomInfo, userChannel.getUserId(), false);
            if (notDealWithHuTask != null && notDealWithHuTask.size() > 0) {
                // 当如果还有未处理hu的  那就不能移除当前任务
                userTask.setRemoveTag(false);
                // 如果说还有 就不能处理
            } else {
                // 将玩家出的牌移除
                CardUtil.removeCard(roomInfo.getUserExportCards().get(prevUserId), prevExportCard);
                // 遍历所有需要胡牌的人
                ArrayList<MahjongUserTask> delWithHuTask = getHuTask(roomInfo, null, true);
                List<Integer> userSeqList = new ArrayList<>();
                for (MahjongUserTask roomTask : delWithHuTask) {
                    MahjongUserChannel userInfo = roomInfo.getUserInfoByUserId(roomTask.getUserId());
                    userInfo.setWin(true);
                    userInfo.setWinCount(userChannel.getWinCount() + 1);
                    userInfo.setFiringUser(prevUserId);
                    userSeqList.add(userInfo.getSeq());
                    userInfo.setHuCard(prevExportCard);
                    // 如果说全部 胡 都处理完毕了 这个时候需要把所有hu的取出来
                    CopyOnWriteArrayList<Integer> userCards = roomInfo.getUserCards().get(roomTask.getUserId());
                    CopyOnWriteArrayList<Integer> temp = new CopyOnWriteArrayList<Integer>(userCards);
                    temp.add(roomInfo.getCurrentExportCard());
                    huCardType = CardUtil.checkCardType(temp, roomInfo.getUserAllTouchBarCards(roomTask.getUserId()));
                    huCardType.addTurns(roomInfo.getCurrentBarUser() != null, userChannel.isListening(), prevUserInfo.isListening(), roomInfo.getRule().getRules().contains(DictionaryConst.MahjongRuleConst.SING_UP) && huCardType.isThreeSteps()
                            , roomInfo.checkFistAndLastFour());
                    BusinessAssertion.isNull("炸胡", huCardType);
                    huCardType.setHuType("放炮");
                    roomInfo.addBillClearingInfo(userInfo, true);
                    roomInfo.addBillHistory(new MahjongBillBuilder().init(CardUtil.ACTION_RECEIVE, huCardType.getType(), userInfo.getUserId(), userChannel.getUserId(), huCardType.getFraction(maxTurns)).build());
                    roomInfo.addBillHistory(new MahjongBillBuilder().init(CardUtil.ACTION_SHOOTING, huCardType.getType(), prevUserId, userChannel.getUserId(), -huCardType.getFraction(maxTurns)).build());
                    // 告诉其他人 我碰牌了
                    diskPart.get(roomInfo.getCode()).notifyMessage(new MessageContent<String>().initActionAndUId(CARD_HU,userChannel.getUserId()), null);
                }
                userSeqList.sort(Comparator.naturalOrder());
                roomInfo.setRoomTask(null);
                // 这里的序列应该是 前面数组递归后的结果
                licensingCard(false, userSeqList.get(0), roomInfo, loadingDealWith, diskPartService, true);
            }
        }
        //发牌操作
        // licensingCard(false, userChannel.getSeq(), roomInfo, loadingDealWith, diskPartService, true);
        //  一下操作是将所有不是胡牌的  或者不带有胡牌的 或者 已经处理了 但是不是胡牌的 直接移除掉
        updateRoomInfo(roomInfo);
    }

    void removeNoHuActionTask(MahjongRoomEntity roomInfo, MetaUserChannel userChannel) {
        ArrayList<MahjongUserTask> roomTask = roomInfo.getRoomTask();
        if (roomTask != null && roomTask.size() > 0) {
            Iterator<MahjongUserTask> iterator = roomTask.iterator();
            while (iterator.hasNext()) {
                MahjongUserTask otherTask = iterator.next();
                // 如果不是当前用户 并且已经处理  并且 处理的 不是胡牌
                if ((!otherTask.getUserId().equals(userChannel.getUserId()) && otherTask.isDealWith() && !otherTask.getDoTask().equals(CARD_HU)) ||
                        (!otherTask.getUserId().equals(userChannel.getUserId()) && !otherTask.isDealWith() && otherTask.getTask() != null && !otherTask.getTask().equals(CARD_HU)) ||
                        (!otherTask.getUserId().equals(userChannel.getUserId()) && !otherTask.isDealWith() && otherTask.getTaskArray() != null && !otherTask.getTaskArray().contains(CARD_HU))
                ) {
                    iterator.remove();
                    // 让用户更新房间信息
                    senMessage(getCtxByUserId(roomInfo.getCode(), otherTask.getUserId()), new MessageContent(MahjongRoomBuilder.inGame(roomInfo, roomInfo.getUserInfoByUserId(otherTask.getUserId())), READ_HOME));
                }
            }
        }
    }
}
